
import OT from './operation.js';

class Rpn {

        constructor(str) {
            this.str = [];
            this.top;
            this.stack = [];
            this.ex = [];
            this._stack = [];
            this.flag = [];
            this.strToArray(str);
        }

        strToArray(str) {
            if (str) {
                this.str = str.split('');
            }
            //console.log(this.str);
        }

//         createRpn() {
//                 
//             let ch = this.str[0];
//             let i = 1, t = 0;
//             this.top = 0;
//             while (ch != '#' && ch != null) {
//                 switch (ch) {
//                     case '(':
//                         this.top++;
//                         this.stack[this.top] = ch;
//                         break;
//                     case ')':
//                         while (this.stack[this.top] != '(') {
//                             this.ex[t] = this.stack[this.top];
//                             this.top--;
//                             t++;
//                             if(this.top <= -1) {
//                                 console.error("不符合运算规则");
//                                 throw {msg: '不符合运算规则'};
//                             }
//                         }
//                         this.top--;
//                         break;
//                     case '+':
//                     case '-':
//                         let temp = Number(this.str[i]);
//                         if (!isNaN(temp) && isNaN(this.str[i - 2]) && this.str[i - 2] != ')') {
//                             this.flag[t] = 1;
//                             this.ex[t++] = ch;
//                             ch = this.str[i++];
//                             while ((ch >= '0' && ch <= '9' || ch == '.')) {
//                                 this.ex[t] = ch;
//                                 t++;
//                                 ch = this.str[i];
//                                 i++;
//                             }
//                             i--;
//                             this.ex[t] = '&';
//                             t++;
//                         } else {
//                             while (this.top != 0 && this.stack[this.top] != '(') {
//                                 this.ex[t] = this.stack[this.top];
//                                 this.top--;
//                                 t++;
//                             }
//                             this.top++;
//                             this.stack[this.top] = ch;
//                         }
//                         break;
//                     case '*':
//                     case '/':
// 					    //运算符^优先级高于*和/
//                         while (this.stack[this.top] == '*' || this.stack[this.top] == '/' || this.stack[this.top] == '^') {
//                             this.ex[t] = this.stack[this.top];
//                             this.top--;
//                             t++;
//                         }
//                         this.top++;
//                         this.stack[this.top] = ch;
//                         break;
//                     case ' ':
//                         break;
//                     default:
//                         //	判别小数点
//                         while ((ch >= '0' && ch <= '9') || ch == '.') {
//                             this.ex[t] = ch;
//                             t++;
//                             ch = this.str[i];
//                             i++;
//                         }
//                         i--;
//                         this.ex[t] = '&';
//                         t++;
//                 }
//                 ch = this.str[i];
//                 i++;
//             }
// 
//             while (this.top != 0) {
//                 if (this.stack[this.top] != '(') {
//                     this.ex[t] = this.stack[this.top];
//                     t++;
//                     this.top--;
//                 } else {
//                     console.error("不符合运算规则");
//                     this.top--;
//                     throw {msg: '不符合运算规则'};
//                 }
//                 this.ex[t] = '#';
//                 //console.log(this.ex);
//             }
//         }
// 


	 createRpn() {
		 let ch = this.str[0];
      let i = 1, t = 0;
      this.top = 0;
      while (ch != '#' && ch != null) {
        switch (ch) {
          case '(':
            this.top++;
            this.stack[this.top] = ch;
            break;
          case ')':
            while (this.stack[this.top] != '(') {
              this.ex[t] = this.stack[this.top];
              this.top--;
              t++;
              if (this.top <= -1) {
                console.error("不符合运算规则");
                throw { msg: '不符合运算规则' };
              }
            }
            this.top--;
            break;
          case '+':
          case '-':
            let temp = Number(this.str[i]);
            if (!isNaN(temp) && isNaN(this.str[i - 2]) && this.str[i - 2] != ')') {
              this.flag[t] = 1;
              this.ex[t++] = ch;
              ch = this.str[i++];
              while ((ch >= '0' && ch <= '9' || ch == '.')) {
                this.ex[t] = ch;
                t++;
                ch = this.str[i];
                i++;
              }
              i--;
              this.ex[t] = '&';
              t++;
            } else {
              while (this.top != 0 && this.stack[this.top] != '(') {
                this.ex[t] = this.stack[this.top];
                this.top--;
                t++;
              }
              this.top++;
              this.stack[this.top] = ch;
            }
            break;
          case '*':
          case '/':
            //运算符^优先级高于*和/
            while (this.stack[this.top] == '*' || this.stack[this.top] == '/' || this.stack[this.top] == '^') {
              this.ex[t] = this.stack[this.top];
              this.top--;
              t++;
            }
            this.top++;
            this.stack[this.top] = ch;
            break;
          case ' ':
            break;
          default:
            //	判别小数点
            while ((ch >= '0' && ch <= '9') || ch == '.') {
              this.ex[t] = ch;
              t++;
              ch = this.str[i];
              i++;
            }
            i--;
            this.ex[t] = '&';
            t++;
        }
        ch = this.str[i];
        i++;
      }

      while (this.top != 0) {
        if (this.stack[this.top] != '(') {
          this.ex[t] = this.stack[this.top];
          t++;
          this.top--;
        } else {
          console.error("不符合运算规则");
          this.top--;
          throw { msg: '不符合运算规则' };
        }
        this.ex[t] = '#';
      }
	 }


	calculate() {
		 console.log(this.ex)
      let ch = this.ex[0];
      let t = 0;
      this.top = -1;
      while (ch != '#' && ch != null) {
        if (ch == '&') {
          ch = this.ex[++t];
          continue;
        }
        switch (ch) {
          case '+':
            //'+'表示正号
            if (this.flag[t]) {
              ch = this.ex[++t];
              let dArr = []
              while((ch >= '0' && ch <= '9') || ch == '.') {
                dArr.push(ch)
                ch = this.ex[++t]
              }
              let d = Number(dArr.join(''))
              this.top++;
              this._stack[this.top] = d;
            } else {
              this._stack[this.top - 1] = OT.added(this._stack[this.top - 1], this._stack[this.top]);
              this.top--;
              t++;
            }
            break;
          case '-':
            //'-'表示负号
            if (this.flag[t]) {
              ch = this.ex[++t];
              let dArr = []
              while((ch >= '0' && ch <= '9') || ch == '.') {
                dArr.push(ch)
                ch = this.ex[++t]
              }
              let d = Number(dArr.join(''))
              this.top++;
              this._stack[this.top] = -d;
            } else {
              this._stack[this.top - 1] = (this._stack[this.top - 1] - this._stack[this.top]);
              this.top--;
              t++;
            }
            break;
          case '^':   //运算符为'^'
            if (this._stack[this.top] == 0) {
              this._stack[this.top - 1] = 1;
            } else {
              let temp;
              temp = this._stack[this.top - 1];
              while (--this._stack[this.top]) {
                this._stack[this.top - 1] *= temp;
              }
            }
            this.top--;
            t++;
            break;
          case '*':
            this._stack[this.top - 1] = (this._stack[this.top - 1] * this._stack[this.top]);
            this.top--;
            t++;
            break;
          case '/':
            if (this._stack[this.top] != 0)
              this._stack[this.top - 1] = (this._stack[this.top - 1] / this._stack[this.top]);
            else {
              console.error("除数不能为0");
              throw { msg: '除数不能为0' };
            }
            this.top--;
            t++;
            break;
          default:
            let dArr = []
              while((ch >= '0' && ch <= '9') || ch == '.') {
                dArr.push(ch)
                ch = this.ex[++t]
              }
            let d = Number(dArr.join(''))
            this.top++;
            this._stack[this.top] = d;
        }
        ch = this.ex[t];
      }
      return this._stack[this.top];
	}
}
//         calculate() {
//             let ch = this.ex[0];
//             let t = 0;
//             this.top = -1;
// 
//             while (ch != '#' && ch != null) {
//                 if (ch == '&') {
//                     ch = this.ex[++t];
//                     continue;
//                 }
//                 switch (ch) {
//                     case '+':
//                         //'+'表示正号
//                         if (this.flag[t]) {
//                             ch = this.ex[++t];
//                             let d = 0;
//                             while (ch >= '0' && ch <= '9') {
//                                 d = OT.added(OT.accMul(10.0, d), parseFloat(ch - '0'));
//                                 ch = this.ex[++t];
//                             }
//                             //判断是否为小数
//                             if (ch == '.') {
//                                 ch = this.ex[++t];
//                                 let k = 1.0;
//                                 while (ch >= '0' && ch <= '9') {
//                                     d = OT.added(d, OT.accDiv(parseFloat(ch - '0'), (10.0 * k)));
//                                     k = k + 1.0;
//                                     ch = this.ex[++t];
//                                 }
//                             }
//                             this.top++;
//                             this._stack[this.top] = d;
//                         } else {
//                             this._stack[this.top - 1] = OT.added(this._stack[this.top - 1], this._stack[this.top]);
//                             this.top--;
//                             t++;
//                         }
//                         break;
//                     case '-':
//                         //'-'表示负号
//                         if (this.flag[t]) {
//                             ch = this.ex[++t];
//                             let d = 0;
//                             while (ch >= '0' && ch <= '9') {
//                                 d = OT.added(OT.accMul(10.0, d), parseFloat(ch - '0'));
//                                 ch = this.ex[++t];
//                             }
//                             if (ch == '.') {
//                                 ch = this.ex[++t];
//                                 let k = 1.0;
//                                 while (ch >= '0' && ch <= '9') {
//                                     d = OT.added(d, OT.accDiv(parseFloat(ch - '0'), (10.0 * k)));
//                                     k = k + 1.0;
//                                     ch = this.ex[++t];
//                                 }
//                             }
//                             this.top++;
//                             this._stack[this.top] = -d;
//                         } else {
//                             this._stack[this.top - 1] = OT.subtract(this._stack[this.top - 1], this._stack[this.top]);
//                             this.top--;
//                             t++;
//                         }
//                         break;
//                     case '^':   //运算符为'^'
//                         if (this._stack[this.top] == 0) {
//                             this._stack[this.top - 1] = 1;
//                         } else {
//                             let temp;
//                             temp = this._stack[this.top - 1];
//                             while (--this._stack[this.top]) {
//                                 this._stack[this.top - 1] *= temp;
//                             }
//                         }
//                         this.top--;
//                         t++;
//                         break;
//                     case '*':
//                         this._stack[this.top - 1] = OT.accMul(this._stack[this.top - 1], this._stack[this.top]);
//                         this.top--;
//                         t++;
//                         break;
//                     case '/':
//                         if (this._stack[this.top] != 0)
//                             this._stack[this.top - 1] = OT.accDiv(this._stack[this.top - 1], this._stack[this.top]);
//                         else {
//                             console.error("除数不能为0");
//                             throw {msg: '除数不能为0'};
//                         }
//                         this.top--;
//                         t++;
//                         break;
//                     default:
//                         let d = 0;
//                         while (ch >= '0' && ch <= '9') {
//                             d = OT.added(OT.accMul(10.0, d), parseFloat(ch - '0'));
//                             ch = this.ex[++t];
//                         }
//                         //判断是否为小数
//                         if (ch == '.') {
//                             ch = this.ex[++t];
//                             let k = 1.0;
//                             while (ch >= '0' && ch <= '9') {
//                                 d = OT.added(d, OT.accDiv(parseFloat(ch - '0'), Math.pow(10.0, k)));
//                                 k = k + 1.0; 
//                                 ch = this.ex[++t];
//                             }
//                         }
//                         this.top++;
//                         this._stack[this.top] = d;
//                 }
//                 ch = this.ex[t];
//             }
//             return this._stack[this.top];
//         }
//     }


export default {
	Rpn
}